/**
 * 
 */
package p;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.security.cert.X509Certificate;
import java.util.Properties;

import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.bouncycastle.jce.PKCS10CertificationRequest;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.PEMWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Panxiaobo
 * 
 */
public class CSRServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private CertManager certManager = new CertManager();

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig)
	 */
	@Override
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		try {
			certManager.getDefaultCA();
		} catch (Exception e) {
			log.warn("初始化certManager异常", e);
			throw new RuntimeException(e);
		}
	}

	private static final Logger log = LoggerFactory.getLogger(CSRServlet.class);

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest
	 * , javax.servlet.http.HttpServletResponse)
	 */
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		try {
			Properties props = new Properties();
			Session session = Session.getDefaultInstance(props, null);
			MimeMessage message = new MimeMessage(session, req.getInputStream());
			Message msg = new MimeMessage(session);
			msg.setFrom(new InternetAddress("ca-no-replay@pxb-ca.appspotmail.com", "Pxb Test CA"));
			log.debug("Message from {}", message.getFrom());
			msg.addRecipients(Message.RecipientType.TO, message.getFrom());
			String text = null;
			log.debug("content-type is {}", message.getContentType());
			if (message.getContent() instanceof Multipart) {
				Multipart multipart = (Multipart) message.getContent();
				log.debug("multipart.count is {}", multipart.getCount());
				for (int i = 0; i < multipart.getCount(); i++) {
					BodyPart bp = multipart.getBodyPart(i);
					if (bp.getContentType().toLowerCase().startsWith("text/plain")) {
						text = (String) bp.getContent();
						break;
					}
					log.debug("mp.{} is {}{}", new Object[] { i, bp.getContentType(), bp.getContent() });
				}
			} else {
				text = message.getContent().toString();
			}
			if (text != null) {
				try {

					log.debug("CSR is \n{}", text);
					String csrPOM = text;
					PKCS10CertificationRequest csr = (PKCS10CertificationRequest) new PEMReader(
							new StringReader(csrPOM)).readObject();
					if (csr == null) {
						throw new Exception("Can't find CSR.");
					}
					boolean server = false;
					for (Address a : message.getRecipients(Message.RecipientType.TO)) {
						server = a.toString().toLowerCase().contains("server");
						if (server)
							break;
					}
					log.debug("is a server csr ? {}", server);
					X509Certificate certificate = certManager.sign(csr, server);
					StringWriter sw = new StringWriter();
					sw.append("\nYOUR Certificate:\n");
					PEMWriter writer = new PEMWriter(sw);
					writer.writeObject(certificate);
					writer.flush();
					sw.append("\nThe CA Certificate:\n");
					writer.writeObject(certManager.getDefaultCA());
					writer.flush();
					writer.close();
					msg.setSubject("CSR回复");
					msg.setText(sw.getBuffer().toString());
				} catch (Exception e) {
					log.warn("处理请求时发生异常", e);
					msg.setSubject("处理请求时发生异常");
					StringWriter sw = new StringWriter();
					e.printStackTrace(new PrintWriter(sw));
					msg.setText(sw.getBuffer().toString());
				}
			} else {
				msg.setSubject("不合法的CSR请求");
				msg.setText("您发送的CSR请求不合法.");
			}
			Transport.send(msg);
		} catch (MessagingException e) {
			throw new RuntimeException(e);
		}
	}
}
